<!DOCTYPE html>
<!--
Copyright 2019 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/extras/chrome/speed_index_utils.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {
  test('getSnapshotsProgress_', function() {
    // Initially, screenshot consists of 3 white pixels.
    const firstScreenshot = [255, 255, 255, 255,
      255, 255, 255, 255,
      255, 255, 255, 255];
    const firstColorHistogram =
    tr.e.chrome.SpeedIndex.createColorHistogram(firstScreenshot);

    // One red pixel, 2 white pixels.
    const secondScreenshot = [255, 0, 0, 255,
      255, 255, 255, 255,
      255, 255, 255, 255];
    const secondColorHistogram =
    tr.e.chrome.SpeedIndex.createColorHistogram(secondScreenshot);

    // One red pixel, one green pixel and one white pixel.
    const thirdScreenshot = [255, 0, 0, 255,
      0, 255, 0, 255,
      255, 255, 255, 255];
    const thirdColorHistogram =
    tr.e.chrome.SpeedIndex.createColorHistogram(thirdScreenshot);

    // One red pixel, one green pixel and one blue pixel.
    const fourthScreenshot = [255, 0, 0, 255,
      0, 255, 0, 255,
      0, 0, 255, 255];
    const fourthColorHistogram =
    tr.e.chrome.SpeedIndex.createColorHistogram(fourthScreenshot);

    const timestampedColorHistograms = new Array(4);
    timestampedColorHistograms[0] =
    {colorHistogram: firstColorHistogram, ts: 100};
    timestampedColorHistograms[1] =
    {colorHistogram: secondColorHistogram, ts: 200};
    timestampedColorHistograms[2] =
    {colorHistogram: thirdColorHistogram, ts: 300};
    timestampedColorHistograms[3] =
    {colorHistogram: fourthColorHistogram, ts: 400};

    const snapshotsProgress =
    tr.e.chrome.SpeedIndex.getSnapshotsProgress_(timestampedColorHistograms);
    assert.strictEqual(4, snapshotsProgress.length);

    assert.closeTo(0, snapshotsProgress[0].value, 1e-7);
    assert.strictEqual(100, snapshotsProgress[0].ts);

    assert.closeTo(1 / 3, snapshotsProgress[1].value, 1e-7);
    assert.strictEqual(200, snapshotsProgress[1].ts);

    assert.closeTo(2 / 3, snapshotsProgress[2].value, 1e-7);
    assert.strictEqual(300, snapshotsProgress[2].ts);

    assert.closeTo(1, snapshotsProgress[3].value, 1e-7);
    assert.strictEqual(400, snapshotsProgress[3].ts);
  });

  test('speedIndexFromSnapshotsProgress_general', function() {
    const speedIndex = tr.e.chrome.SpeedIndex.speedIndexFromSnapshotsProgress_(
        [{value: 0, ts: 100}, {value: 0.5, ts: 200}, {value: 1.0, ts: 300}]);
    assert.strictEqual(250, speedIndex);
  });

  test('speedIndexFromSnapshotsProgress_empty', function() {
    assert.throws(() =>
      tr.e.chrome.SpeedIndex.speedIndexFromSnapshotsProgress_([]),
    'No snapshots were provided.');
  });

  test('speedIndexFromSnapshotsProgress_zerosThenOne', function() {
    const speedIndex = tr.e.chrome.SpeedIndex.speedIndexFromSnapshotsProgress_(
        [{value: 0, ts: 100}, {value: 0, ts: 200}, {value: 1.0, ts: 300}]);
    assert.strictEqual(300, speedIndex);
  });

  test('speedIndexFromSnapshotsProgress_allOnes', function() {
    const speedIndex = tr.e.chrome.SpeedIndex.speedIndexFromSnapshotsProgress_(
        [{value: 1.0, ts: 100}, {value: 1.0, ts: 200}, {value: 1.0, ts: 300}]);
    assert.strictEqual(100, speedIndex);
  });

  test('speedIndexFromSnapshotsProgress_oneObject', function() {
    const speedIndex = tr.e.chrome.SpeedIndex.speedIndexFromSnapshotsProgress_(
        [{value: 1, ts: 100}]);
    assert.strictEqual(100, speedIndex);
  });

  test('createColorHistogram', function() {
    const colorHistogram =
    tr.e.chrome.SpeedIndex.createColorHistogram([255, 0, 0, 255,
      0, 255, 0, 255,
      0, 0, 255, 255,
      255, 255, 0, 255]);
    const histogram = new Array(3);
    for (let i = 0; i < 3; i++) {
      histogram[i] = new Array(256).fill(0.0);
    }
    // Update red channel values.
    histogram[0][255] = 2;
    histogram[0][0] = 2;
    // Update green channel values.
    histogram[1][255] = 2;
    histogram[1][0] = 2;
    // Update blue channel values.
    histogram[2][255] = 1;
    histogram[2][0] = 3;

    assert.deepEqual(histogram, colorHistogram);
  });

  test('lineSweepDuplicateRect', function() {
    const lineSweepRects = [{left: 50, right: 60, top: 70, bottom: 100},
      {left: 50, right: 60, top: 70, bottom: 100}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(300,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('lineSweepNonOverlappingRects', function() {
    const lineSweepRects = [{left: 50, right: 60, top: 70, bottom: 100},
      {left: 10, right: 20, top: 30, bottom: 50}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(500,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('lineSweepOverlappingRects', function() {
    const lineSweepRects = [{left: 30, right: 60, top: 70, bottom: 100},
      {left: 20, right: 50, top: 30, bottom: 80},
      {left: 40, right: 70, top: 10, bottom: 40}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(3000,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('lineSweepOverlappingAndNonOverlappingRects', function() {
    const lineSweepRects = [{left: 30, right: 60, top: 70, bottom: 100},
      {left: 20, right: 50, top: 30, bottom: 80},
      {left: 40, right: 70, top: 10, bottom: 40},
      {left: 110, right: 120, top: 30, bottom: 40}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(3100,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('lineSweepOutsideViewport', function() {
    const lineSweepRects = [{left: 150, right: 160, top: 70, bottom: 100}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(0,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('lineSweepOverlapWithViewport', function() {
    const lineSweepRects = [{left: 140, right: 160, top: 70, bottom: 100}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(300,
        tr.e.chrome.SpeedIndex.lineSweep(lineSweepRects, viewport));
  });

  test('quadToRect', function() {
    const quad = [10, 30, 20, 30, 20, 50, 10, 50];
    const rect = {left: 10, right: 20, top: 30, bottom: 50};
    assert.deepEqual(rect, tr.e.chrome.SpeedIndex.quadToRect(quad));
  });

  test('calculateRectsBasedSpeedIndex', function() {
    const timestampedPaintRects =
    [{rect: {left: 50, right: 60, top: 70, bottom: 100}, ts: 500},
      {rect: {left: 10, right: 20, top: 30, bottom: 50}, ts: 700}];
    const viewport = {x: 0, y: 0, width: 150, height: 150};
    assert.strictEqual(580,
        tr.e.chrome.SpeedIndex.calculateRectsBasedSpeedIndex(
            timestampedPaintRects, viewport));
  });
});
</script>
